Next | Prev | Up | Top | Contents | Index

Process Execution

An activity process that is enqueued to a Frame Scheduler has the basic structure shown in Example 7-1.

Example 7-1 : Skeleton of an Activity Process

/* Initialize data structures etc. */
frs_join(scheduler-handle)
do
{
   /* Perform the activity. */
   frs_yield();
} while(1);
_exit(); 
When the process is ready to start real-time execution, it calls frs_join(). This call blocks until all enqueued processes are ready and scheduling begins (see "Starting Multiple Schedulers"). When frs_join() returns, the process is running in its first minor-frame execution.

The process then performs whatever activity it is supposed to complete in each minor frame. When it completes that work, it calls frs_yield(). This gives up control of the CPU until the next minor frame in which the process is enqueued.

An activity process is never preempted. As long as it yields before the end of the frame, it can do its assigned work without interruption from other processes (it can be interrupted by hardware interrupts, if any hardware interrupts are allowed in that CPU). The Frame Scheduler preempts the process at the end of the minor frame.

Tip: Because an activity process cannot be preempted, it can often use global data without locks or semaphores. When the process that modifies a global variable is enqueued in a different minor frame from the processes that read the variable, there can be no access conflicts between them. Conflicts are still possible between two processes that are queued to the same minor frame in different, synchronized Frame Schedulers. However, such processes are guaranteed to be running concurrently. This means they can use spin-locks (see "Locks") with high efficiency.

Tip: When a very short minor frame interval is used, it is possible for a process to have an overrun error in its first frame due to cache misses. A simple variation on the basic structure shown in Example 7-1 is to spend the first minor frame touching a set of important data structures in order to "warm up" the cache (see "Reducing Cache Misses"). This is sketched in Example 7-2.

Example 7-2 : Alternate Skeleton of Activity Process

/* Initialize data structures etc. */
frs_join(scheduler-handle); /* Much time could pass here. */
/* First frame: merely touch important data structures. */
do
{
   frs_yield();
   /* Second and later frames: perform the activity. */
} while(1);
_exit(); 
When an activity process is scheduled on more than one minor frame in a major frame, it can be designed to do nothing except warm the cache in the entire first major frame. To do this, the activity process function has to know how many minor frames it is scheduled on, and calls frs_yield() that many times in order to pass the first major frame.


Next | Prev | Up | Top | Contents | Index